昨天提到了 Example code 來囉!
我這邊先用新的專案來改
第一步我們需要先建立一個 model,記得要 with ChangeNotifier,
這樣才能調用 notifyListeners()
讓有使用的這個 model 的人知道要重新渲染囉~
import 'package:flutter/foundation.dart';
class Counter with ChangeNotifier {
int _value;
int get value => _value;
Counter(this._value);
void incrementCounter() {
_value++;
notifyListeners();
}
}
然後我們要用 ChangeNotifierProvider
builder 是個 function 回傳我們新建的 model
這樣我們在 MaterialApp 底下所有的 Widget 就都可以拿到這個Counter.value了呢!
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
builder: (_) => Counter(0),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
),
);
}
}
讓我們來看看要怎麼取用吧!
有兩種方式,
Provider.of<Counter>(context, listen: <bool>).value
這邊有個參數,listen 如果給 false 可以讓他不監聽 notifyListeners 而重新渲染
常用在如果只是想調用一個 function 時可以使用,避免不必要的重新渲染。
Consumer(
builder: (_, counter, ch) => Text(
'${counter.value}',
style: Theme.of(context).textTheme.display1,
),
)
這個方法可以做局部的監聽 Provider。
以下是取用 counter 方法,與 counter 加一的簡單範例。
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Consumer<Counter>(
builder: (_, counter, ch) => Text(
'${counter.value}',
style: Theme.of(context).textTheme.display1,
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Counter>(context, listen: false).incrementCounter();
},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
還有一些特殊情況下會使用的方法,之後專案用到時會一併說明。